/*
 * @Author: ReinerLau lk850593913@gmail.com
 * @Date: 2023-02-22 11:09:47
 * @LastEditors: ReinerLau lk850593913@gmail.com
 * @LastEditTime: 2023-02-27 11:27:43
 * @FilePath: \v2.0.0\src\views\patroling\composables\useInitMap.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import { createRedArrow } from "../shared";
import { fetchList } from "@/api/robot-vehicle-log.js";
import usePatrolingStore from "@/store/patroling";
import { computed, onMounted, reactive } from "vue";
import usePollingUpdate from "./usePollingUpdate";
import { uniqWith, isEqual } from "lodash";

export default (key: string) => {
  const patrolingData = usePatrolingStore();

  const {
    updateExcutingMission,
    watchHeadingChange,
    watchMissionChange,
    watchPositionChange,
  } = usePollingUpdate();

  onMounted(async () => {
    patrolingData.map = renderMap();
    patrolingData.map.layers.insert(getTileSource());
    patrolingData.drawingTools = await initDrawingTools();
    handleEditPath();
    patrolingData.excutingLayer = initExcutingLayer();
    initExcutingMission();
    patrolingData.previewLayer = initPreviewLayer();
    patrolingData.carMarks = await initCarMarks();
    getCarMarkLoaction();
    patrolingData.backToCenter();
    watchHeadingChange();
    watchPositionChange();
    watchMissionChange();
  });

  const pinLoaction = reactive({
    latitude: null,
    longitude: null,
  });
  const pinLoactionText = computed(() => {
    if (pinLoaction.latitude === null || pinLoaction.longitude === null)
      return "";
    return `坐标：(${pinLoaction.latitude}, ${pinLoaction.longitude})`;
  });

  return {
    pinLoactionText,
  };

  function renderMap() {
    return new Microsoft.Maps.Map("#bmap", {
      // key 来自于 https://www.bingmapsportal.com/ 登录账号后 My account - My Keys
      credentials: key,
      // 默认使用卫星地图
      mapTypeId: Microsoft.Maps.MapTypeId.aerial,
      zoom: 19,
      maxZoom: 19,
      enableClickableLogo: false,
      showMapTypeSelector: false,
      showLocateMeButton: false,
      showZoomButtons: false,
      showTermsLink: false,
    });
  }

  // 解决获取卫星地图需要翻墙的问题
  function getTileSource() {
    const tileSource = new Microsoft.Maps.TileSource({
      // 通过 https://dev.ditu.live.com/REST/V1/Imagery/Metadata/Aerial?uriScheme=https&o=json&key={BingMapsKey} 生成 uriConstructor，参考 https://learn.microsoft.com/en-us/bingmaps/rest-services/imagery/get-imagery-metadata
      uriConstructor:
        "https://t{subdomain}.ssl.ak.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=13184",
      maxZoom: 19,
    });
    return new Microsoft.Maps.TileLayer({
      mercator: tileSource,
      zIndex: 0,
    });
  }

  // 初始化绘制路径点的工具模块
  function initDrawingTools(): Promise<Microsoft.Maps.DrawingTools> {
    return new Promise((resolve) => {
      Microsoft.Maps.loadModule("Microsoft.Maps.DrawingTools", () => {
        resolve(new Microsoft.Maps.DrawingTools(patrolingData.map));
      });
    });
  }

  // 初始化放置正在执行路径点的图层
  function initExcutingLayer() {
    const result = new Microsoft.Maps.Layer();
    patrolingData.map.layers.insert(result);
    return result;
  }

  // 初始化创建路径点的图层
  function initPreviewLayer() {
    const result = new Microsoft.Maps.Layer();
    patrolingData.map.layers.insert(result);
    return result;
  }

  // 初始化车辆标记
  async function initCarMarks(): Promise<Microsoft.Maps.Pushpin[]> {
    const { data } = await fetchList({
      page: 1,
      limit: 10,
    });
    const list = data.list || [];
    const result = generatePins(list);
    patrolingData.map.entities.push(result);
    return result;

    function generatePins(list) {
      return list.map((item) => {
        const latitude = item.latitude || 0;
        const longitude = item.longitude || 0;
        const location = new Microsoft.Maps.Location(latitude, longitude);
        return new Microsoft.Maps.Pushpin(location, {
          title: item.robotid,
          icon: createRedArrow(0),
        });
      });
    }
  }

  function initExcutingMission() {
    updateExcutingMission(patrolingData.patrolingInfo.missionId);
  }

  function getCarMarkLoaction() {
    patrolingData.carMarks.forEach((pin) => {
      Microsoft.Maps.Events.addHandler(pin, "mouseover", () => {
        const location = pin.getLocation();
        pinLoaction.latitude = location.latitude;
        pinLoaction.longitude = location.longitude;
      });
      Microsoft.Maps.Events.addHandler(pin, "mouseout", () => {
        pinLoaction.latitude = null;
        pinLoaction.longitude = null;
      });
    });
  }

  function handleEditPath() {
    Microsoft.Maps.Events.addHandler(
      patrolingData.drawingTools,
      "drawingChanged",
      (polyline) => {
        let points = polyline.geometry.x.map((x, index) => ({
          longitude: x,
          latitude: polyline.geometry.y[index],
        }));
        points = uniqWith(points, isEqual);
        patrolingData.createdPath = points.map((item) => ({
          x: item.latitude,
          y: item.longitude,
        }));
        patrolingData.updatePathPoint();
      }
    );
  }
};
